package com.msh.artascope.devcloud.service.util;

import com.msh.frame.client.exception.MshRuntimeException;
import com.msh.frame.web.filter.RestTemplateLogInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.ssl.TrustStrategy;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

@Slf4j
public class RestTemplateUtil {

  public static RestTemplate newNoCheckSslRestTemplate(){
    try {
      RestTemplate restTemplate = new RestTemplate(generateHttpRequestFactory());
      restTemplate.getMessageConverters().stream().forEach(c->{
        if(c instanceof StringHttpMessageConverter){
          StringHttpMessageConverter converter = (StringHttpMessageConverter) c;
          converter.setDefaultCharset(StandardCharsets.UTF_8);
        }
      });
      restTemplate.setInterceptors(Arrays.asList(new RestTemplateLogInterceptor()));
      return restTemplate;
    }catch (Exception e){
      log.error("创建不验证证书的RestTemplate失败", e);
      throw new MshRuntimeException("创建不验证证书的RestTemplate失败");
    }
  }

  private static HttpComponentsClientHttpRequestFactory generateHttpRequestFactory()
      throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException
  {
    TrustStrategy acceptingTrustStrategy = (x509Certificates, authType) -> true;
    SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
    SSLConnectionSocketFactory connectionSocketFactory = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());

    HttpClientBuilder httpClientBuilder = HttpClients.custom();
    httpClientBuilder.setSSLSocketFactory(connectionSocketFactory);
    CloseableHttpClient httpClient = httpClientBuilder.build();
    HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
    factory.setHttpClient(httpClient);
    return factory;
  }
}
